using Microsoft.SPOT.Hardware;
using Microsoft.SPOT;
using System;

namespace CSharpDuino
{
    public delegate void ButtonClick();
    public delegate void ButtonDown();
    public delegate void ButtonUp();

    public class Button
    {
        private readonly InputPort buttonPort;

        private bool lastState = false;
        private bool newState = false;

        private DateTime lastEvent;

        public event ButtonDown ButtonDown;
        public event ButtonUp ButtonUp;
        public event ButtonClick ButtonClick;

        private readonly string ButtonPortName;

        public Button(Cpu.Pin port)
        {
            this.ButtonPortName = port.ToString();
            this.buttonPort = new InputPort(port, false, Port.ResistorMode.PullUp);
            this.lastEvent = DateTime.Now;
        }

        public void ReadState()
        {
            newState = buttonPort.Read();

            var delta = DateTime.Now.Ticks - lastEvent.Ticks;

            if (!lastState && newState)
            {
                Debug.Print("*** Raise Button[" + this.ButtonPortName + "] UP ***");
                lastEvent = DateTime.Now;
                if (this.ButtonUp != null)
                {
                    this.ButtonUp();
                }
            }

            if (!lastState && newState)
            {
                Debug.Print("*** Raise Button[" + this.ButtonPortName + "] Click ***");
                lastEvent = DateTime.Now;
                Debug.Print(delta.ToString());
                if (700000 < delta && delta < 400000000)
                {
                    Debug.Print("*** Raise Event ***");
                    if (this.ButtonClick != null)
                    {
                        this.ButtonClick();
                    }
                }
            }

            if (lastState && !newState)
            {
                Debug.Print("*** Raise Button[" + this.ButtonPortName + "] DOWN ***");
                lastEvent = DateTime.Now;
                if (this.ButtonDown != null)
                {
                    this.ButtonDown();
                }
            }

            lastState = newState;
        }
    }
}
